﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace new_problem
{
    internal class FastestWay
    {
        public static Double[,] CalcFastestWay(double[,] g, double[] x, double[] y, DataBuffer current)
        {
            double eps = 0.01; // рекомендуемая точность
            Double[,] z0 = DataGen.StartApproximation(); // начальное приближение
            Double[,] A = DataGen.GetFieldGrid(x, y, z0);
            Double[,] dA = DataGen.GetFieldDerivative(x, y, z0);
            Double[,] dAt = MiscUtils.TransposeMatrix(dA);
            double alpha = 2/0.1;
            Double[,] zk = new double[DataGen.N + 1, DataGen.N + 1]; // for result

            double nrm = MiscUtils.Norm(g); // ||g||
            double err = 1.0;
            int k = 0;
            while (err > eps && k < 5000)
            {
                Double[,] S = MiscUtils.CalcS(A, dAt, g);
                double num = Math.Pow(MiscUtils.Norm(S), 2);
                double den = MiscUtils.CalcDenominator(dA, S);
                double coef = num/den;
                double stabFunc = DataGen.StabilisingFunctional(A);
                for (int i = 0; i <= DataGen.N; i++)
                    for (int j = 0; j <= DataGen.N; j++)
                        zk[i, j] = z0[i, j] - alpha*coef*S[i, j];
                z0 = zk;
                A = DataGen.GetFieldGrid(x, y, z0);
                dA = DataGen.GetFieldDerivative(x, y, z0);
                dAt = MiscUtils.TransposeMatrix(dA);
                err = MiscUtils.Norm(MiscUtils.SubstractMatrix(A, g));
                err /= nrm;
                k++;
                //alpha = 0.1;
                Console.WriteLine("FW:" + k + ": " + err + ", alpha: " + alpha);
            }
            current.Fw = k;
            current.FwErr = err;
            return zk;
        }
    }
}
